package org.spring.springboot.app.file.service.impl;

import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ZipUtil;
import cn.novelweb.tool.http.Result;
import cn.novelweb.tool.io.FileUtils;
import cn.novelweb.tool.upload.local.LocalUpload;
import cn.novelweb.tool.upload.local.pojo.UploadFileParam;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.obs.services.model.*;
import com.qcloud.cos.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.spring.springboot.app.base.R;
import org.spring.springboot.app.base.Type;
import org.spring.springboot.app.file.dao.*;
import org.spring.springboot.app.file.domain.po.*;
import org.spring.springboot.app.file.domain.vo.FileSearchVO;
import org.spring.springboot.app.file.domain.vo.FileVO;
import org.spring.springboot.app.file.service.IFileService;
import org.spring.springboot.app.file.task.CompanyThread;
import org.spring.springboot.exception.BusinessException;
import org.spring.springboot.util.DateUtils;
import org.spring.springboot.util.KeyUtil;
import org.spring.springboot.util.ObsUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.InputStream;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


@Service
@Transactional
public class FileServiceImpl implements IFileService {
    @Value("${server.url}")
    private String server_url;


    @Autowired
    private CompanyFileDao fileDao;
    @Autowired
    private VideoDao videoDao;
    @Autowired
    private CompanyDao companyDao;
    @Autowired
    private DramasDao dramasDao;
    @Autowired
    private ResourceFileShardDao resourceFileShardDao;
    @Autowired
    private VideoDownloadLogDao videoDownloadLogDao;

    private final static Log log = LogFactory.getLog(IFileService.class);

    @Override
    public R upload(MultipartFile file, String appId) {
        R r = new R();
        if (StringUtils.isBlank(appId)) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        CompanyPO companyPO= companyDao.selectByPrimaryKey(appId);
        if (companyPO == null&&!appId.equals("888888")&&!appId.equals("999999")) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        if (file.isEmpty()) {
            return r.set(Type.FILE_EXCEPTION_NULL);
        }
        String fileName = file.getOriginalFilename(); // 获取文件名
        String suffixName = "";
        if (fileName.contains(".")) {
            suffixName = fileName.substring(fileName.lastIndexOf("."));// 获取文件的后缀名
        }
        String timeDirectory = DateUtils.getDate("yyyy/MMdd");
        String id = IdUtil.getSnowflakeNextIdStr();
        String path = timeDirectory;
        String name = id + suffixName;
        //保存新文件 video.yujuyi.com  file.yujuyi.com
        String newFileName = id + suffixName;//新文件名
        String relativePath = appId + "/" + timeDirectory + "/" + newFileName;//文件上传手的相对路径
        String realPath = System.getProperty("user.dir") + "/file/" + relativePath;// 文件上传后的绝对路径
        realPath.replaceAll("//", "/");
        File dest = new File(realPath);
        if (!dest.getParentFile().exists()) {// 检测是否存在目录
            dest.getParentFile().mkdirs();
        }
        CompanyFilePO filePO = new CompanyFilePO();
        try {
            file.transferTo(dest);
            filePO.setId(id);
            filePO.setFileName(fileName);
            filePO.setCompanyId(appId);
            filePO.setFileRealPath(realPath);
            filePO.setFileFullPath(server_url  + "/file/" + relativePath);
            filePO.setFileSize(new BigDecimal((float) file.getSize() / 1024).setScale(2, BigDecimal.ROUND_HALF_UP));
            filePO.setFileType(getFileType(suffixName));
            filePO.setFileSuffix(suffixName);
            filePO.setCreateDate(new Date());
            fileDao.insertSelective(filePO);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("数据保存失败");
        }
        FileVO vo = new FileVO();
        vo.setId(id);
        vo.setFileSize(new BigDecimal((float) file.getSize() / 1024).setScale(2, BigDecimal.ROUND_HALF_UP) + "KB");
        vo.setFilePath(server_url  + "/file/" + relativePath);
        vo.setType(filePO.getFileType());
//        if(companyPO!=null){
//            new CompanyThread(companyDao,companyPO,filePO.getFileSize()).run();
//        }
        return r.setData(vo);
    }


    @Override
    public R upload_obs(MultipartFile file, String appId) {
        R r = new R();
        if (StringUtils.isBlank(appId)) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        CompanyPO companyPO= companyDao.selectByPrimaryKey(appId);
        if (companyPO == null&&!appId.equals("888888")&&!appId.equals("999999")) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        if (file.isEmpty()) {
            return r.set(Type.FILE_EXCEPTION_NULL);
        }
        String timeDirectory = DateUtils.getDate("yyyyMMdd");
        String fileName = timeDirectory+"_"+file.getOriginalFilename(); // 获取文件名
        String suffixName = "";
        if (fileName.contains(".")) {
            suffixName = fileName.substring(fileName.lastIndexOf("."));// 获取文件的后缀名
        }
        String id = IdUtil.getSnowflakeNextIdStr();
        //保存新文件
        String relativePath = "file/"+appId;//文件上传手的相对路径
        String HuaWeiUrl="http://file.yujuyi.com";
        if(getFileType(suffixName)==2){
            relativePath="history/"+appId;//文件上传手的相对路径
            HuaWeiUrl="http://video.yujuyi.com";
        }
        //保存新文件 video.yujuyi.com  file.yujuyi.com
        CompanyFilePO filePO = new CompanyFilePO();
        try {
            PutObjectResult putObjectResult = ObsUtils.uploadFile(file,relativePath, fileName);
            log.info( putObjectResult.toString());
            filePO.setId(id);
            filePO.setFileName(fileName);
            filePO.setCompanyId(appId);
            filePO.setFileRealPath(relativePath+"/"+fileName);
            filePO.setFileFullPath(HuaWeiUrl+"/"+filePO.getFileRealPath());
            filePO.setFileSize(new BigDecimal((float) file.getSize() / 1024).setScale(2, BigDecimal.ROUND_HALF_UP));
            filePO.setFileType(getFileType(suffixName));
            filePO.setFileSuffix(suffixName);
            filePO.setCreateDate(new Date());
            fileDao.insertSelective(filePO);
        } catch (Exception e) {
//            e.printStackTrace();
            throw new RuntimeException("数据保存失败");
        }
        FileVO vo = new FileVO();
        vo.setId(id);
        vo.setFileSize(new BigDecimal((float) file.getSize() / 1024).setScale(2, BigDecimal.ROUND_HALF_UP) + "KB");
        vo.setFilePath(filePO.getFileFullPath());
        vo.setType(filePO.getFileType());
//        if(companyPO!=null){
//            new CompanyThread(companyDao,companyPO,filePO.getFileSize()).run();
//        }
        return r.setData(vo);
    }

    public static Cache<String,String> fifoCache = CacheUtil.newFIFOCache(1000);

    @Override
    public R upload_shard(UploadFileParam uploadFileParam, String appId,  HttpServletRequest request) {
//        String id = IdUtil.getSnowflakeNextIdStr();
//        String newFileName = id + uploadFileParam.getName();//新文件名
//        uploadFileParam.setName(newFileName);
        String companyId=fifoCache.get(appId);
        if(StringUtils.isBlank(companyId)){
            CompanyPO companyPO= companyDao.selectByPrimaryKey(appId);
            if (companyPO == null&&!appId.equals("888888")&&!appId.equals("999999")) {
                return new R().set(Type.FILE_EXCEPTION_FORMAT);
            }
            fifoCache.put(appId,appId, DateUnit.SECOND.getMillis() *60*30 );
        }
        try {
            String timeDirectory = DateUtils.getDate("yyyy/MMdd");
            String relativePath = appId + "/" + timeDirectory + "/";//文件上传手的相对路径
            String realPath = System.getProperty("user.dir") + "/file/" + relativePath;// 文件上传后的绝对路径
            LocalUpload.fragmentFileUploader(uploadFileParam, realPath+"/conf", realPath, 5242880L, request);
            ResourceFileShardPO resourceFileShardPO=new ResourceFileShardPO();
            resourceFileShardPO.setFileId(uploadFileParam.getMd5());
            resourceFileShardPO.setId(IdUtil.getSnowflakeNextIdStr());
            resourceFileShardPO.setShardChunk(uploadFileParam.getChunk());
            resourceFileShardPO.setShardChunks(uploadFileParam.getChunks());
            resourceFileShardPO.setShardName(uploadFileParam.getName());
            resourceFileShardPO.setShardSize(uploadFileParam.getFile().getSize());
            resourceFileShardDao.insertSelective(resourceFileShardPO);
        }catch (Exception e){
            e.printStackTrace();
        }
        return new R();
    }

    @Override
    public R upload_shard_obs(UploadFileParam uploadFileParam, String appId, HttpServletRequest request) {
        String suffixName = "";
        if (uploadFileParam.getName().contains(".")) {
            suffixName = uploadFileParam.getName().substring(uploadFileParam.getName().lastIndexOf("."));// 获取文件的后缀名
        }
        String relativePath = "file/"+appId;//文件上传手的相对路径
        if(getFileType(suffixName)==2){
            relativePath="history/"+appId;//文件上传手的相对路径
        }
        try {
            String uploadFile = fifoCache.get(uploadFileParam.getMd5());
            if(StringUtils.isBlank(uploadFile)){
                String timeDirectory = DateUtils.getDate("yyyyMMdd");
                uploadFileParam.setName(timeDirectory+"_"+uploadFileParam.getName()); // 获取文件名
                String uploadId = ObsUtils.InitiateMultipartUploadRequest(relativePath+"/"+uploadFileParam.getName());
                uploadFile=uploadId+"=="+uploadFileParam.getName();
                fifoCache.put(uploadFileParam.getMd5(),uploadFile);
            }
            String[] uploadS=uploadFile.split("==");
            String updateId=uploadS[0];
            String fileName=uploadS[1];
            UploadPartResult result=ObsUtils.uploadPart(relativePath+"/"+fileName,updateId,uploadFileParam.getChunk()+1,uploadFileParam.getFile());
            ResourceFileShardPO resourceFileShardPO=new ResourceFileShardPO();
            resourceFileShardPO.setShardEtag(result.getEtag());
            resourceFileShardPO.setFileId(uploadFileParam.getMd5());
            resourceFileShardPO.setId(IdUtil.getSnowflakeNextIdStr());
            resourceFileShardPO.setShardChunk(uploadFileParam.getChunk());
            resourceFileShardPO.setShardChunks(uploadFileParam.getChunks());
            resourceFileShardPO.setShardName(uploadFileParam.getName());
            resourceFileShardPO.setShardSize(uploadFileParam.getFile().getSize());
            resourceFileShardDao.insertSelective(resourceFileShardPO);
        }catch (Exception e){
            e.printStackTrace();
        }
        return new R();
    }

//    public static void main(String[] args) {
//        String filename = "20231212_太空滴滴（1）.mp4";
//        if (filename.contains("_")) {
//            filename = filename.substring(filename.lastIndexOf("_")+1,filename.length());// 获取文件的后缀名
//        }
//        System.out.println(filename);
//    }
    @Override
    public R download_obs(String appId,String url, HttpServletRequest request, HttpServletResponse response) {
        log.info(url);
        url = KeyUtil.decryptFromString(url.replaceAll("\n","").replaceAll("\r",""));
        log.info(url);
        R r=new R();
        if (StringUtils.isBlank(appId)) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        CompanyPO companyPO= companyDao.selectByPrimaryKey(appId);
        if (companyPO == null&&!appId.equals("888888")&&!appId.equals("999999")) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        String zuan="";
        Example videoExample=new Example(VideoPO.class);
        videoExample.and().andEqualTo("videoOldUrl",url);
        VideoPO videoPO=videoDao.selectOneByExample(videoExample);
//        CompanyFilePO companyFilePO=fileDao.selectByPrimaryKey(videoPO.getVideoFileId());
        if(videoPO==null){
            videoExample=new Example(VideoPO.class);
            videoExample.and().andEqualTo("videoUrl",url);
            videoPO=videoDao.selectOneByExample(videoExample);
            zuan="转码";
//            companyFilePO=fileDao.selectByPrimaryKey(videoPO.getVideoFileId());
//            companyFilePO.setFileFullPath(url.replaceAll("http://video.yujuyi.com/",""));
        }
        if(videoPO==null){
            return r.set(Type.FILE_EXCEPTION_NOT_NULL);
        }
        String fileFullPath=url.replaceAll("http://video.yujuyi.com/","");
//        if(companyFilePO==null){
//            return r.set(Type.FILE_EXCEPTION_NOT_NULL);
//        }
        try {
            ObsObject obsObject = ObsUtils.getObject(fileFullPath);
            InputStream input = obsObject.getObjectContent();
            //缓冲文件输出流
            BufferedOutputStream  outputStream = new BufferedOutputStream(response.getOutputStream());
            String encodedFilename = new String((zuan+videoPO.getVideoAllName()).getBytes("UTF-8"), "ISO-8859-1");
            //设置让浏览器弹出下载提示框，而不是直接在浏览器中打开
            response.addHeader("Content-Disposition", "attachment;filename=" +encodedFilename);
            IOUtils.copy(input,outputStream);
            outputStream.flush();
            outputStream.close();
            input.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return r;
    }

    public static void main(String[] args) {
        System.out.println("http://220.200.155.28:20803/file/373247/2023/1117/1725330559695155200.jpg".indexOf("http://220.200.155.28:20803"));
    }
    @Override
    public R delete_file(String appId, String url) {
        R r=new R();
        if(!appId.equals("sakdhiqowhiohi131231313")){
            return r.set(Type.NO_AUTHORITY);
        }
        try {
            if(url.indexOf(server_url)>=0){
                //删除本地资源
                String path= System.getProperty("user.dir") +url.replaceAll(server_url,"");
                FileUtil.del(path);
            }else{
                //删除华为云资源
                String path=url.replaceAll("http://video.yujuyi.com/","").replaceAll("http://file.yujuyi.com/","");
                log.info(path);
                ObsUtils.deleteFile(path);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return r;
    }

    @Override
    public R download(String appId, String url, HttpServletRequest request, HttpServletResponse response) {
        R r=new R();
        if (!appId.equals("888888")&&!appId.equals("999999")) {
            return r.set(Type.FILE_EXCEPTION_FORMAT);
        }
        Example example=new Example(CompanyFilePO.class);
        example.and().andEqualTo("fileFullPath",url);
        CompanyFilePO filePO=fileDao.selectOneByExample(example);
        if (filePO==null){
            return r.set(Type.FILE_EXCEPTION_NOT_NULL);
        }

        try {
            InputStream input =FileUtil.getInputStream(new File(filePO.getFileRealPath()));
            //缓冲文件输出流
            BufferedOutputStream  outputStream = new BufferedOutputStream(response.getOutputStream());
            String encodedFilename = new String((filePO.getFileName()).getBytes("UTF-8"), "ISO-8859-1");
            //设置让浏览器弹出下载提示框，而不是直接在浏览器中打开
            response.addHeader("Content-Disposition", "attachment;filename=" +encodedFilename);
            IOUtils.copy(input,outputStream);
            outputStream.flush();
            outputStream.close();
            input.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return r;
    }

    @Override
    public R video_download(String videoId,String userId, Integer type, HttpServletRequest request, HttpServletResponse response) {
        VideoPO videoPO=videoDao.selectByPrimaryKey(videoId);
        R r=new R();
        if(videoPO==null){
            return r.set(Type.FILE_EXCEPTION_NOT_NULL);
        }
        String fileFullPath=type==1?videoPO.getVideoOldUrl().replaceAll("http://video.yujuyi.com/",""):videoPO.getVideoUrl().replaceAll("http://video.yujuyi.com/","");

        VideoDownloadLogPO videoDownloadLogPO=new VideoDownloadLogPO();
        videoDownloadLogPO.setId(IdUtil.getSnowflakeNextIdStr());
        videoDownloadLogPO.setVideoId(videoPO.getId());
        videoDownloadLogPO.setVideoAllName(videoPO.getVideoAllName());
        videoDownloadLogPO.setVideoGather(videoPO.getVideoGather());
        videoDownloadLogPO.setVideoName(videoPO.getVideoName());
        videoDownloadLogPO.setVideoRef(videoPO.getVideoRef());
        videoDownloadLogPO.setCreateBy(userId);
        videoDownloadLogPO.setCreateDate(new Date());
        videoDownloadLogPO.setUpdateDate(videoDownloadLogPO.getCreateDate());
        videoDownloadLogPO.setUpdateBy(videoDownloadLogPO.getCreateBy());
        videoDownloadLogDao.insertSelective(videoDownloadLogPO);

        try {
            ObsObject obsObject = ObsUtils.getObject(fileFullPath);
            InputStream input = obsObject.getObjectContent();
            //缓冲文件输出流
            BufferedOutputStream  outputStream = new BufferedOutputStream(response.getOutputStream());
            String encodedFilename = new String(((type==1?"":"转码-")+videoPO.getVideoAllName()).getBytes("UTF-8"), "ISO-8859-1");
            //设置让浏览器弹出下载提示框，而不是直接在浏览器中打开
            response.addHeader("Content-Disposition", "attachment;filename=" +encodedFilename);
            IOUtils.copy(input,outputStream);
            outputStream.flush();
            outputStream.close();
            input.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return r;
    }

    @Override
    public R drama_video_download(String dramaId,String userId, Integer type, HttpServletRequest request, HttpServletResponse response) {
        try {
            DramasPO dramasPO=dramasDao.selectByPrimaryKey(dramaId);
            Example example=new Example(VideoPO.class);
            example.and().andEqualTo("dramaId",dramaId).andEqualTo("videoDownloadState",3);
            List<VideoPO> videoList=videoDao.selectByExample(example);
            if(videoList!=null&&videoList.size()>0){
                List<File> videoFiles=new ArrayList<>();
                for (VideoPO videoPO:videoList){

                    String fileFullPath=type==1?videoPO.getVideoOldUrl().replaceAll("http://video.yujuyi.com/",""):videoPO.getVideoUrl().replaceAll("http://video.yujuyi.com/","");
                    ObsObject obsObject = ObsUtils.getObject(fileFullPath);
                    InputStream input = obsObject.getObjectContent();
                    File videoFile = FileUtil.file(System.getProperty("user.dir") + "/zip/"+dramaId+"/log/"+(type==1?"":"转码-")+videoPO.getVideoAllName());
                    FileUtils.toFile(input,videoFile);
                    videoFiles.add(videoFile);
                }
                File file= ZipUtil.zip(System.getProperty("user.dir") + "/zip/"+dramaId+"/log/",System.getProperty("user.dir") + "/zip/"+dramaId+"/"+(type==1?"":"转码-")+dramasPO.getDramaName()+".zip", false);
                //设置响应头
                response.setContentType("application/octet-stream");
                String encodedFilename = new String(file.getName().getBytes("UTF-8"), "ISO-8859-1");
                response.setHeader("Content-Disposition", "attachment;filename=" + encodedFilename);
                ServletOutputStream out = response.getOutputStream();
                out.write(FileUtil.readBytes(file));
                out.flush();
                //关闭流
                out.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public R checkFileMd5(String appId, String md5,String fileName,Integer type) throws Exception {
        Example example=new Example(CompanyFilePO.class);
        example.and().andEqualTo("fileKey",md5).andEqualTo("companyId",appId);
        CompanyFilePO companyFilePO=fileDao.selectOneByExample(example);
        if(companyFilePO!=null){
            if(StringUtils.isNotBlank(companyFilePO.getFileFullPath())){
                return new R().setMessage("文件已经上传");
            }
        }
        Example fileExample=new Example(ResourceFileShardPO.class);
        fileExample.and().andEqualTo("fileId",md5);
        fileExample.setOrderByClause("shard_chunk asc");
        List<ResourceFileShardPO> list=resourceFileShardDao.selectByExample(fileExample);
        List<String> missChunkList = new LinkedList();
        if(list!=null&&list.size()>0){
            ResourceFileShardPO one=list.get(0);
            if(list.size()==one.getShardChunks()){
                return new R().setMessage("文件已经上传");
            }
            Map<Integer, Integer> chunkMap = list.stream().collect(Collectors.toMap(ResourceFileShardPO::getShardChunk, ResourceFileShardPO::getShardChunk));
            for (int i = 0; i < one.getShardChunks() ; i++) {
                if(!chunkMap.containsKey(i)){
                    missChunkList.add(Integer.toString(i));
                }
            }
        }else{
            if(type==1){
                if(!fifoCache.containsKey(md5)){
                    String timeDirectory = DateUtils.getDate("yyyyMMdd");
                    fileName = timeDirectory+"_"+fileName; // 获取文件名

                    String suffixName = "";
                    if (fileName.contains(".")) {
                        suffixName = fileName.substring(fileName.lastIndexOf("."));// 获取文件的后缀名
                    }
                    String relativePath = "file/"+appId;//文件上传手的相对路径
                    if(getFileType(suffixName)==2){
                        relativePath="history/"+appId;//文件上传手的相对路径
                    }
                    String uploadId = ObsUtils.InitiateMultipartUploadRequest(relativePath+"/"+fileName);
                    fifoCache.put(md5,uploadId+"=="+fileName);
                }
            }
            return new R(Type.FILE_NULL);
        }
        JSONArray jsonArray = JSON.parseArray(JSONObject.toJSONString(missChunkList));
        return new R(Type.EXIST).setData(jsonArray);
    }

    @Override
    public R successFile(String appId, String md5,Integer type,String fileName,Long fileSize) throws Exception {
        Example example=new Example(CompanyFilePO.class);
        example.and().andEqualTo("fileKey",md5).andEqualTo("companyId",appId);
        CompanyFilePO companyFilePO=fileDao.selectOneByExample(example);
        if(companyFilePO!=null){
            FileVO vo = new FileVO();
            vo.setId(companyFilePO.getId());
            vo.setFileSize(companyFilePO.getFileSize() + "KB");
            vo.setFilePath(companyFilePO.getFileFullPath());
            vo.setType(companyFilePO.getFileType());
            return new R(vo).setMessage("文件已经上传");
        }
        CompanyFilePO filePO = new CompanyFilePO();
        String id = IdUtil.getSnowflakeNextIdStr();
        filePO.setId(id);

        CompanyPO companyPO= companyDao.selectByPrimaryKey(appId);
        if (companyPO == null&&!appId.equals("888888")&&!appId.equals("999999")) {
            return new R().set(Type.FILE_EXCEPTION_FORMAT);
        }
        String suffixName = "";
        if (fileName.contains(".")) {
            suffixName = fileName.substring(fileName.lastIndexOf("."));// 获取文件的后缀名
        }
        filePO.setId(id);
        filePO.setCompanyId(appId);
        filePO.setFileKey(md5);
        filePO.setFileSize(new BigDecimal((float) fileSize / 1024).setScale(2, BigDecimal.ROUND_HALF_UP));
        filePO.setFileType(getFileType(suffixName));
        filePO.setFileSuffix(suffixName);
        filePO.setCreateDate(new Date());
        if(type==2){
            String timeDirectory = DateUtils.getDate("yyyy/MMdd");
            String path = timeDirectory;
            String relativePath = appId + "/" + timeDirectory + "/" + fileName;//文件上传手的相对路径
            String realPath = System.getProperty("user.dir") + "/file/" + relativePath;// 文件上传后的绝对路径
            realPath.replaceAll("//", "/");
            filePO.setFileName(fileName);
            filePO.setFileRealPath(realPath);
            filePO.setFileFullPath(server_url  + "/file/" + relativePath);
        }
        if(type==1&&fifoCache.containsKey(md5)){
            String uploadFile = fifoCache.get(md5);
            String[] uploadS=uploadFile.split("==");
            String updateId=uploadS[0];
            String fileNames=uploadS[1];
            //保存新文件
            String relativePath = "file/"+appId;//文件上传手的相对路径
            String HuaWeiUrl="http://file.yujuyi.com";
            if(getFileType(suffixName)==2){
                relativePath="history/"+appId;//文件上传手的相对路径
                HuaWeiUrl="http://video.yujuyi.com";
            }
            filePO.setFileName(fileNames);
            filePO.setFileRealPath(relativePath+"/"+fileNames);
            filePO.setFileFullPath(HuaWeiUrl+"/"+filePO.getFileRealPath());
            Example fileExample=new Example(ResourceFileShardPO.class);
            fileExample.and().andEqualTo("fileId",md5);
            fileExample.setOrderByClause("shard_chunk asc");
            List<ResourceFileShardPO> list=resourceFileShardDao.selectByExample(fileExample);
            List<PartEtag> etagList =new ArrayList<>();
            for (ResourceFileShardPO resourceFileShardPO:list){
                PartEtag partEtag=new PartEtag();
                partEtag.setEtag(resourceFileShardPO.getShardEtag());
                partEtag.setPartNumber(resourceFileShardPO.getShardChunk()+1);
                etagList.add(partEtag);
            }
            ObsUtils.completeMultipartUpload(relativePath+"/"+fileNames,updateId,etagList);
            fifoCache.remove(md5);
        }

        fileDao.insertSelective(filePO);
        FileVO vo = new FileVO();
        vo.setId(id);
        vo.setFileSize(filePO.getFileSize() + "KB");
        vo.setFilePath(filePO.getFileFullPath());
        vo.setType(filePO.getFileType());
//        if(companyPO!=null){
//            new CompanyThread(companyDao,companyPO,filePO.getFileSize()).run();
//        }
        return new R().setData(vo);
    }




//    @Override
//    public R<FileVO> upload_obs_s(MultipartFile file, String appId) {
//        R r = new R();
//        String timeDirectory = DateUtils.getDate("yyyyMMdd");
//        String fileName = timeDirectory+"_"+file.getOriginalFilename(); // 获取文件名
//        String suffixName = "";
//        if (fileName.contains(".")) {
//            suffixName = fileName.substring(fileName.lastIndexOf("."));// 获取文件的后缀名
//        }
//        String id = IdUtil.getSnowflakeNextIdStr();
//        //保存新文件
//        String relativePath = "file/"+appId;//文件上传手的相对路径
//        String HuaWeiUrl="http://file.yujuyi.com";
//        if(getFileType(suffixName)==2){
//            relativePath="history/"+appId;//文件上传手的相对路径
//            HuaWeiUrl="http://video.yujuyi.com";
//        }
//        try {
//            PutObjectResult putObjectResult = ObsUtils.uploadFile(file,relativePath, fileName);
//            log.info( putObjectResult.toString());
//        } catch (Exception e) {
//            e.printStackTrace();
//            throw new RuntimeException("数据保存失败");
//        }
//        FileVO vo = new FileVO();
//        vo.setId(id);
//        vo.setFileSize(new BigDecimal((float) file.getSize() / 1024).setScale(2, BigDecimal.ROUND_HALF_UP) + "KB");
//        vo.setFilePath(HuaWeiUrl+"/"+relativePath+"/"+fileName);
//        vo.setType(getFileType(suffixName));
//        return r.setData(vo);
//    }


    @Override
    public R delete(String fileId, String appId) {
        Example example = new Example(CompanyFilePO.class);
        example.and().andEqualTo("id", fileId);
        CompanyFilePO companyFilePO = fileDao.selectOneByExample(example);
        if (companyFilePO == null) {
            return  new R(Type.FILE_EXCEPTION_NOT_NULL);
        }
        if (!companyFilePO.getCompanyId().equals(appId)) {
            return  new R(Type.FILE_EXCEPTION_FORMAT);
        }
        File file = new File(companyFilePO.getFileRealPath());
        if (!file.exists()) {
            return new R(Type.FILE_EXCEPTION_FORMAT);
        }
        file.delete();
        fileDao.deleteByPrimaryKey(fileId);
        return new R();
    }

    @Override
    public R getOne(String fileId, String appId) {
        Example example = new Example(CompanyFilePO.class);
        example.and().andEqualTo("id", fileId);
        CompanyFilePO companyFilePO = fileDao.selectOneByExample(example);
        if (companyFilePO == null) {
            return new R(Type.FILE_EXCEPTION_NOT_NULL);
        }
        if (!companyFilePO.getCompanyId().equals(appId)) {
            return new R(Type.FILE_EXCEPTION_FORMAT);
        }

        FileVO vo = new FileVO();
        vo.setId(companyFilePO.getId());
        vo.setFileSize(companyFilePO.getFileSize() + "KB");
        vo.setFilePath(companyFilePO.getFileFullPath());
        return new R(vo);
    }

    @Override
    public R deletePath(String filePath, String appId) {
        Example example = new Example(CompanyFilePO.class);
        example.and().andEqualTo("fileFullPath", filePath);
        CompanyFilePO companyFilePO = fileDao.selectOneByExample(example);
        if (companyFilePO == null) {
            return  new R(Type.FILE_EXCEPTION_NOT_NULL);
        }
        if (!companyFilePO.getCompanyId().equals(appId)) {
            return  new R(Type.FILE_EXCEPTION_FORMAT);
        }
        File file = new File(companyFilePO.getFileRealPath());
        if (!file.exists()) {
            return new R(Type.FILE_EXCEPTION_FORMAT);
        }
        file.delete();
        fileDao.deleteByPrimaryKey(companyFilePO.getId());
        return  new R();
    }

    @Override
    public List<FileVO> getList(FileSearchVO searchVO) {
        return  fileDao.getList(searchVO);
    }


    private Integer getFileType(String suffixName) {
        Integer type = 6;
        //文件类型：1.图片 2.视频 3.网页相关文件 4.压缩包 5.excel文件 6. 其它
        //图片 .jpg .jpeg .gif .png .bmp
        //视频 .mp4 .3gp .m4v .mpg .avi
        //网页相关文件 .html .js .css
        //压缩包 .zip .rar
        //excel文件 .xls .xlsx
        //其它
        switch (suffixName) {
            case ".zip":
                type = 4;
                break;
            case ".rar":
                type = 4;
                break;
            case ".xls":
                type = 5;
                break;
            case ".xlsx":
                type = 5;
                break;
            case ".jpg":
                type = 1;
                break;
            case ".jpeg":
                type = 1;
                break;
            case ".gif":
                type = 1;
                break;
            case ".png":
                type = 1;
                break;
            case ".bmp":
                type = 1;
                break;
            case ".mp4":
                type = 2;
                break;
            case ".3gp":
                type = 2;
                break;
            case ".m4v":
                type = 2;
                break;
            case ".mpg":
                type = 2;
                break;
            case ".mov":
                type = 2 ;
            case ".wmv":
                type = 2 ;
            case ".mkv":
                type = 2 ;
            case ".wav":
                type = 2 ;
            case ".ts":
                type = 2 ;
            case ".flv":
                type = 2 ;
            case ".avi":
                type = 2;
                break;
            case ".html":
                type = 3;
                break;
            case ".css":
                type = 3;
                break;
            case ".js":
                type = 3;
                break;
        }
        return type;
    }


}
